home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
ada
/
gnat1792.zip
/
gnat179b
/
t-adainc
/
a-calend.adb
< prev
next >
Wrap
Text File
|
1994-05-19
|
15KB
|
422 lines
------------------------------------------------------------------------------
-- --
-- GNAT RUNTIME COMPONENTS --
-- --
-- A D A . C A L E N D A R --
-- --
-- B o d y --
-- --
-- $Revision: 1.16 $ --
-- --
-- Copyright (c) 1992,1993,1994 NYU, All Rights Reserved --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 2, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License --
-- for more details. You should have received a copy of the GNU General --
-- Public License distributed with GNAT; see file COPYING. If not, write --
-- to the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. --
-- --
------------------------------------------------------------------------------
with System; use System;
with System.Task_Clock;
with System.Task_Clock.Machine_Specifics;
pragma Checks_On;
-- We require checks on for this body, because we rely on the constraint
-- error to keep Calendar.Time values within representable range.
package body Ada.Calendar is
-- Type definitions for Unix functions localtime and mktime
type Char_Pointer is access Character;
type tm is record
tm_sec : Integer range 0 .. 60; -- seconds after the minute
tm_min : Integer range 0 .. 59; -- minutes after the hour
tm_hour : Integer range 0 .. 23; -- hours since midnight
tm_mday : Integer range 1 .. 31; -- day of the month
tm_mon : Integer range 0 .. 11; -- months since January
tm_year : Integer; -- years since 1900
tm_wday : Integer range 0 .. 6; -- days since Sunday
tm_yday : Integer range 0 .. 365; -- days since January 1
tm_isdst : Integer range 0 .. 1; -- Daylight Savings Time flag
tm_gmtoff : Long_Integer; -- offset from CUT in seconds
tm_zone : Char_Pointer; -- timezone abbreviation
end record;
type tm_Pointer is access tm;
subtype time_t is Long_Integer;
type time_t_Pointer is access time_t;
function localtime (C : time_t_Pointer) return tm_Pointer;
pragma Import (C, localtime);
function mktime (TM : tm_Pointer) return time_t;
pragma Import (C, mktime);
-- mktime returns -1 in case the calendar time given by components of
-- TM.all cannot be represented.
-- The following constants are used in adjusting Ada dates so that they
-- fit into the range that can be handled by Unix (1970 - 2062). The trick
-- is that the number of days in any four year period in the Ada range of
-- years (1901 - 2099) has a constant number of days. This is because we
-- have the special case of 2000 which, contrary to the normal exception
-- for centuries, is a leap year after all.
Unix_Year_Min : constant := 1970;
Unix_Year_Max : constant := 2062;
Ada_Year_Min : constant := 1901;
Ada_Year_Max : constant := 2099;
Days_In_Month : constant array (Month_Number) of Day_Number :=
(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
Days_In_4_Years : constant := 365 * 3 + 366;
Seconds_In_4_Years : constant := 86_400 * Days_In_4_Years;
Seconds_In_4_YearsD : constant Duration := Duration (Seconds_In_4_Years);
---------
-- "+" --
---------
function "+" (Left : Time; Right : Duration) return Time is
begin
return (Left + Time (Right));
exception
when Constraint_Error => raise Time_Error;
end "+";
function "+" (Left : Duration; Right : Time) return Time is
begin
return (Left + Time (Right));
exception
when Constraint_Error => raise Time_Error;
end "+";
---------
-- "-" --
---------
function "-" (Left : Time; Right : Duration) return Time is
begin
return Left - Time (Right);
exception
when Constraint_Error => raise Time_Error;
end "-";
function "-" (Left : Time; Right : Time) return Duration is
begin
return Duration (Left) - Duration (Right);
exception
when Constraint_Error => raise Time_Error;
end "-";
---------
-- "<" --
---------
function "<" (Left, Right : Time) return Boolean is
begin
return Duration (Left) < Duration (Right);
end "<";
----------
-- "<=" --
----------
function "<=" (Left, Right : Time) return Boolean is
begin
return Duration (Left) <= Duration (Right);
end "<=";
---------
-- ">" --
---------
function ">" (Left, Right : Time) return Boolean is
begin
return Duration (Left) > Duration (Right);
end ">";
----------
-- ">=" --
----------
function ">=" (Left, Right : Time) return Boolean is
begin
return Duration (Left) >= Duration (Right);
end ">=";
-----------
-- Clock --
-----------
-- The Ada.Calendar.Clock function gets the time from the GNULLI
-- interface routines. This ensures that Calendar is properly
-- coordinated with the tasking runtime. Any system dependence
-- involved in reading the clock is then hidden in the GNULLI
-- implementation layer (in the body of System.Task_Clock).
function Clock return Time is
begin
return Time (Task_Clock.Stimespec_To_Duration (
Task_Clock.Machine_Specifics.Clock));
end Clock;
---------
-- Day --
---------
function Day (Date : Time) return Day_Number is
DY : Year_Number;
DM : Month_Number;
DD : Day_Number;
DS : Day_Duration;
begin
Split (Date, DY, DM, DD, DS);
return DD;
end Day;
-----------
-- Month --
-----------
function Month (Date : Time) return Month_Number is
DY : Year_Number;
DM : Month_Number;
DD : Day_Number;
DS : Day_Duration;
begin
Split (Date, DY, DM, DD, DS);
return DM;
end Month;
-------------
-- Seconds --
-------------
function Seconds (Date : Time) return Day_Duration is
DY : Year_Number;
DM : Month_Number;
DD : Day_Number;
DS : Day_Duration;
begin
Split (Date, DY, DM, DD, DS);
return DS;
end Seconds;
-----------
-- Split --
-----------
procedure Split
(Date : Time;
Year : out Year_Number;
Month : out Month_Number;
Day : out Day_Number;
Seconds : out Day_Duration)
is
-- The following declare bounds for duration that are comfortably
-- wider than the maximum allowed output result for the Ada range
-- of representable split values. These are used for a quick check
-- that the value is not wildly out of range.
Low : constant := (Ada_Year_Min - Unix_Year_Min - 2) * 365 * 86_400;
High : constant := (Ada_Year_Max - Unix_Year_Max + 2) * 365 * 86_400;
LowD : constant Duration := Duration (Low);
HighD : constant Duration := Duration (High);
-- The following declare the maximum duration value that can be
-- successfully converted to a 32-bit integer suitable for passing
-- to the localtime function. It might be more correct to use the
-- value Integer'Last here, but i